/**
 * 
 */
package com.gr.staffpm.form.validation;

import java.util.HashMap;
import java.util.Map;

import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.validation.AbstractFormValidator;
import org.apache.wicket.util.lang.Objects;
import org.apache.wicket.validation.IValidationError;
import org.apache.wicket.validation.ValidationError;

import com.gr.staffpm.properties.PropertiesController;


/**
 * Validates that neither of the input of two form components is not empty and they are both equal. 
 * Also validates that the password is the configured characters length (default 8).
 * 
 * Errors are reported with the key 'PasswordInputValidator' and the variables:
 * <ul>
 * <li>${input(n)}: the user's input</li>
 * <li>${name}: the name of the component</li>
 * <li>${password.length}: the application configured length for a password.</li>
 * <li>${label(n)}: the label of the component - either comes from
 * FormComponent.labelModel or resource key [form-id].[form-component-id] in
 * that order</li>
 * </ul>
 * 
 * @author Graham Rhodes 7 Mar 2011 18:31:04
 */
public class PasswordInputValidator extends AbstractFormValidator {

    private static final long serialVersionUID = 1L;
    /** form components to be checked. */
    private final FormComponent<?>[] components;
    private final Map<String, Object> varMap = new HashMap<String, Object>();

    /**
     * Construct.
     * 
     * @param formComponent1
     *            a form component
     * @param formComponent2
     *            a form component
     */
    public PasswordInputValidator(FormComponent<?> formComponent1, FormComponent<?> formComponent2) {
        if (formComponent1 == null) {
            throw new IllegalArgumentException("argument: formComponent1 cannot be null");
        }
        if (formComponent2 == null) {
            throw new IllegalArgumentException("argument: formComponent2 cannot be null");
        }
        components = new FormComponent[] { formComponent1, formComponent2 };

    }

    /**
     * @see wicket.markup.html.form.validation.IFormValidator#getDependentFormComponents()
     */
    @Override
    public FormComponent<?>[] getDependentFormComponents() {
        return components;
    }

    /**
     * @see wicket.markup.html.form.validation.IFormValidator#validate(wicket.markup.html.form.Form)
     */
    @Override
    public void validate(Form<?> form) {
        // we have a choice to validate the type converted values or the raw
        // input values, we validate the raw input
        final FormComponent<?> formComponent1 = components[0];
        final FormComponent<?> formComponent2 = components[1];
        this.varMap.putAll(variablesMap());
        this.varMap.put("password.length", PropertiesController.getInstance().getProperty("password.length", "8"));

        if (Objects.stringValue(formComponent1.getInput(), true).equals("")
                || Objects.stringValue(formComponent2.getInput(), true).equals("")
                || !formComponent1.getInput().equals(formComponent2.getInput())
                || formComponent1.getInput().length() < PropertiesController.getInstance().getPropertyAsInt("password.length", 8)) {
            ValidationError ve = new ValidationError();
            ve.setVariables(PasswordInputValidator.this.varMap);
            ve.addMessageKey(resourceKey());
            formComponent1.error((IValidationError) ve);
        }
    }
}
